#include "../../Helix.h"
#include "../../HObject.h"
#include "../../Log.h"
#include "Image.h"
#include "BMPImage.h"
#include <windows.h>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

namespace helix
{
	
	BMPImage::BMPImage(const char *fileName) : Image(fileName)
	{
		string fName = fileName;
		loaded = loadBitmap(&fName);
		depth = 1;	//BMP images are only 2Dimensional

		if(loaded)
		{
			imageType = "Bitmap";
			swapPixelComponents(Image::RED_CHANNEL,Image::BLUE_CHANNEL);	//swap the first and third component values of every pixel
		}
	}

	BMPImage::~BMPImage()
	{
		if(data!=NULL)
			delete data;
	}

	bool BMPImage::loadBitmap(string *fileName)
	{
		BITMAPFILEHEADER bfh;	//the file header
		BITMAPINFOHEADER bih;	//the info header

		//Open the file for binary reading
		ifstream fileIn(fileName->data(),ifstream::binary);

		//Make sure the file is open
		if(!fileIn.is_open())
		{
			Log().Error("File: %s did not open correctly. ",fileName->data());
			return false;
		}

		//read in the bitmapinfoheader
		fileIn.read((char*)&bfh, sizeof(BITMAPFILEHEADER));

		//verify that this is a bmp file by checking the bitmap id
		if (bfh.bfType !=0x4D42)
		{
			Log().Error("Wrong bitmap ID: %s... ",fileName);
			fileIn.close();
			return false;
		}

		if ( bfh.bfType != 'MB')
		{
			Log().Error("Error, bfType not equal to MB: %s",fileName);
			fileIn.close();
			return false;
		}

		//read the bitmap info header
		fileIn.read((char*)&bih, sizeof(BITMAPINFOHEADER));

		if ( bih.biCompression != BI_RGB)
		{
			Log().Error("Compression not equal to BI_RGB: %s",fileName);
			fileIn.close();
			return false;
		}

		if ( bih.biBitCount != 24 )
		{
			Log().Error("Bitmap not equal to 24 bits: %s",fileName);
			fileIn.close();
			return false;
		}

		int size=bfh.bfSize - bfh.bfOffBits;

		//move file pointer to the begining of bitmap data
		fileIn.seekg(bfh.bfOffBits, ios_base::beg);

		//make room for the size of the image
		data=new vector<unsigned char>(size);

		//read in the bitmap image data
		fileIn.read((char*)&(*data)[0],bih.biSizeImage);

		//was the data read in?
		if(!fileIn.good())
		{
			Log().Error("There was an error reading the data in the bitmap: %s",fileName);
			fileIn.close();
			return false;
		}

		//Close the file
		fileIn.close();

		bpp=bih.biBitCount;
		width=bih.biWidth;
		height=bih.biHeight;
		channels=3;
		return true;
	}

}



